package br.com.rhinovet.faces;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;

import org.primefaces.event.TabChangeEvent;

import br.com.rhinovet.bean.HistoricoBean;
import br.com.rhinovet.bean.HistoricoTable;
import br.com.rhinovet.comparator.DataProcedimentoComparator;
import br.com.rhinovet.entidade.Consulta;
import br.com.rhinovet.entidade.ProcedimentoConsulta;
import br.com.rhinovet.logica.contract.ProcedimentoConsultaLogicaContract;
import br.com.rhinovet.util.DataUtil;
import br.com.rhinovet.util.FacesUtil;

@ManagedBean(name="historicoFaces")
@ViewScoped
public class HistoricoFaces extends FacesUtil {
	
	private static final long serialVersionUID = 1L;

	private Consulta consulta;
	
	private List<HistoricoTable> historicoTable = new ArrayList<>();
	
	@ManagedProperty(value = "#{procedimentoConsultaLogica}")
	private ProcedimentoConsultaLogicaContract procedimentoConsultaLogica;
	
	public HistoricoFaces() {
		this.popularConsultaSessao();
	}
	
	@PostConstruct
	public void init() {
	}
	
	public void buscarProcedimentos(TabChangeEvent event) {
		this.historicoTable.clear();
		if (event.getTab().getId().equalsIgnoreCase("abaHistorico")) {
			if (this.consulta == null) {
				this.popularConsultaSessao();
			}
		
			List<Integer> listaAnos = this.buscarAnos();
			
			for (Integer anoAtual : listaAnos) {
				List<HistoricoBean> listaHistorico = new ArrayList<>();
				Date dataInicioAno = DataUtil.prepararDataInicioAno(anoAtual);
				Date dataFimAno = DataUtil.prepararDataFimAno(anoAtual);
				try {
					List<ProcedimentoConsulta> listaProcedimentos = procedimentoConsultaLogica.buscarProcedimentosPorPeriodoPorConsulta(this.consulta.getId(), dataInicioAno, dataFimAno);
					
					Map<Date, List<ProcedimentoConsulta>> mapRetorno = new HashMap<>();
		
					for (ProcedimentoConsulta itemProcedimento : listaProcedimentos) {
						
						Date dataProcedimento = DataUtil.prepararDataInicioDia(itemProcedimento.getDataProcedimento());
						
						if (mapRetorno.get(dataProcedimento) != null) {
							mapRetorno.get(dataProcedimento).add(itemProcedimento);
						} else {
							List<ProcedimentoConsulta> listaProcedimento = new ArrayList<ProcedimentoConsulta>();
							listaProcedimento.add(itemProcedimento);
							mapRetorno.put(dataProcedimento, listaProcedimento);
						}
					}
					
					for (Map.Entry<Date, List<ProcedimentoConsulta>> item :  mapRetorno.entrySet()) {
						
						HistoricoBean historico = new HistoricoBean();
						historico.setDataProcedimento(item.getKey());
						Map<String, Double> mapTotais = calcularTotaisDia(item.getValue());
						
						historico.setValorTotalBrutoDia("R$ " + String.format("%.2f", (double)   mapTotais.get("valorTotal")));
						historico.setValorTotalLiquidoDia("R$ " + String.format("%.2f", (double) mapTotais.get("valorLiquido")));
						
						historico.setListaProcedimentos(item.getValue());
						listaHistorico.add(historico);
					}
					
				} catch (Exception e) {
					adicionarMensagem("Erro ao buscar os procedimentos");
				}
				
				
				Collections.sort(listaHistorico, new DataProcedimentoComparator());
				
				HistoricoTable notificacao = new HistoricoTable(anoAtual, listaHistorico);
				historicoTable.add(notificacao);
			}
		}
    }
	
	public Map<String, Double> calcularTotaisDia(List<ProcedimentoConsulta> listaProcedimento) {
		
		Map<String, Double> mapRetorno = new HashMap<>();
		mapRetorno.put("valorTotal", 0D);
		mapRetorno.put("valorLiquido", 0D);
		
		for (ProcedimentoConsulta itemProc : listaProcedimento) {
			Double valorTotal = mapRetorno.get("valorTotal") + itemProc.getTotalProcedimento();
			mapRetorno.put("valorTotal", valorTotal);

			Double valorLiquido = mapRetorno.get("valorLiquido") + itemProc.getTotalLiquido();
			mapRetorno.put("valorLiquido", valorLiquido);
		}
		
		return mapRetorno;
	}
	
	public List<Integer> buscarAnos( ) {
		if (this.consulta == null) {
			this.popularConsultaSessao();
		}
		
		try {
			return procedimentoConsultaLogica.buscarAnosProcedimento(this.consulta.getId());
		} catch (Exception e) {
			adicionarMensagem("Não foi possível buscar a lista de anos");
		}
		
		return new ArrayList<>();
	}
	
	public void popularConsultaSessao() {
		Consulta consulta = (Consulta) getSession().getAttribute("consultaSelecionada");
		if (consulta != null) {
			this.consulta = consulta;
		}
	}

	public Consulta getConsulta() {
		return consulta;
	}

	public void setConsulta(Consulta consulta) {
		this.consulta = consulta;
	}

	public void setProcedimentoConsultaLogica(ProcedimentoConsultaLogicaContract procedimentoConsultaLogica) {
		this.procedimentoConsultaLogica = procedimentoConsultaLogica;
	}

	public List<HistoricoTable> getHistoricoTable() {
		return historicoTable;
	}

	public void setHistoricoTable(List<HistoricoTable> historicoTable) {
		this.historicoTable = historicoTable;
	}

	
}